package net.example.manager;

import android.app.Application;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Message;

import com.oraycn.esbasic.helpers.StringHelper;
import com.oraycn.esbasic.loggers.FileLogger;
import com.oraycn.esbasic.loggers.ILogger;
import com.oraycn.esframework.common.LogonResponse;
import com.oraycn.esframework.common.LogonResult;
import com.oraycn.esframework.core.BasicEventListener;
import com.oraycn.esframework.core.ClientType;
import com.oraycn.esframework.core.EngineEventListener;
import com.oraycn.esframework.core.ICustomizeHandler;
import com.oraycn.esframework.core.IRapidPassiveEngine;
import com.oraycn.omcs.MultimediaDeviceType;
import com.oraycn.omcs.MultimediaManagerFactory;
import com.oraycn.omcs.shortMessages.AudioMessage;
import com.oraycn.omcs.utils.BufferUtils;

import net.example.activity.ChatActivity;
import net.example.activity.LoginActivity;
import net.example.activity.SplashActivity;
import net.example.activity.VideoCall4GroupActivity;
import net.example.activity.VideoCallActivity;
import net.example.activity.VideoChat4GroupActivity;
import net.example.activity.VoiceCallActivity;
import net.example.model.AddFriendRequestPage;
import net.example.model.AddGroupRequestPage;
import net.example.model.CommunicateMediaType;
import net.example.model.CommunicateType;
import net.example.model.ContractType;
import net.example.model.GroupChangedType;
import net.example.model.GroupOfflineMessage;
import net.example.model.OfflineMessage;
import net.example.model.GGGroup;
import net.example.model.GGUser;
import net.example.model.SnapchatMessage;
import net.example.model.SnapchatMessageRead;
import net.example.model.UserState;
import net.example.model.UserStatus;
import net.example.model.common.RichChatMessage;
import net.example.model.contract.ChangeCommentNameContract;
import net.example.model.contract.ChangeHeadImageContract;
import net.example.model.contract.ChangeUserBaseInfoContract;
import net.example.model.contract.GroupBan4UserContract;
import net.example.model.contract.HandleAddFriendRequestContract;
import net.example.model.contract.HandleAddGroupRequestContract;
import net.example.model.contract.MediaCommunicateContract;
import net.example.model.contract.MoveFriendToOtherCatalogContract;
import net.example.model.contract.RemoveGroupBan4UserContract;
import net.example.model.contract.RequestAddFriendContract;
import net.example.model.contract.RequestAddGroupContract;
import net.example.model.contract.UserStatusChangedContract;
import net.example.model.event.CallEvent;
import net.example.model.event.ChatEvent;
import net.example.model.event.FriendAddedNotifyEvent;
import net.example.model.event.FriendCatalogChangedEvent;
import net.example.model.event.FriendCommentNameChangedEvent;
import net.example.model.event.FriendDeletedNotifyEvent;
import net.example.model.event.GetAddFriendPageEvent;
import net.example.model.event.GetAddGroupPageEvent;
import net.example.model.event.GroupBan4UserEvent;
import net.example.model.event.GroupDeletedNotifyEvent;
import net.example.model.event.GroupUserChangedEvent;
import net.example.model.event.HandleRequestAddFriendReceivedEvent;
import net.example.model.event.HandleRequestAddGroupReceivedEvent;
import net.example.model.event.RemoveGroupBan4UserEvent;
import net.example.model.event.RequestAddFriendEvent;
import net.example.model.event.RequestAddGroupEvent;
import net.example.model.event.RequestEvent;
import net.example.model.event.SomeoneRegisteredEvent;
import net.example.model.event.UserEvent;
import net.example.model.event.UserInfoChangedEvent;
import net.example.ggtalk.R;
import net.example.utils.CommonOptions;
import net.example.utils.ConfigUtils;
import net.example.utils.IntentUtils;
import net.example.utils.LogHelper;
import net.example.utils.ToastUtils;
import net.example.utils.android.AndroidUtil;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import de.greenrobot.event.EventBus;

import static net.example.utils.ConfigUtils.SDLogSavePath;

public class GGApplication extends Application implements EngineEventListener, BasicEventListener , ICustomizeHandler {

    public static Context applicationContext;
    private static GGApplication instance;
    public String TALKINGUSER = "";
    private IRapidPassiveEngine engine;
    private GGUser currentUser;
    private boolean waitingConnected = false;
    private FileLogger fileLogger;

    @Override
    public void connectionInterrupted() {
        //由于移动网络的不稳定性，此事件被触发的几率比较高
        //引擎会自动（可设置）重连网络，此处适当延时触发掉线事件
        if (!waitingConnected) {
            waitingConnected = true;
            new Thread() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(10 * 1000);
                        if (!engine.connected()) {
                            uiHandler.obtainMessage(0).sendToTarget();
                        }
                        waitingConnected = false;
                    } catch (Exception e) {
                    }
                }
            }.start();
        }
    }

    @Override
    public void relogonCompleted(LogonResponse logonResp) {
        if (logonResp != null && logonResp.getLogonResult() == LogonResult.Succeed) {
            Manager.getInstance().changeMyStatus(UserStatus.Online);
            uiHandler.obtainMessage(2).sendToTarget();
            Manager.getInstance().requestMyOfflineMessage();
        }
    }
    @Override
    public void connectionRebuildStart() {
        uiHandler.obtainMessage(1);
    }

    private Handler uiHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0) {
                CommonOptions.CallingID4VideoOrVoice="";
                ToastUtils.showLong(GGApplication.applicationContext, "您已掉线,请检查相关网络设置");
                EventBus.getDefault().post(new RequestEvent(null,null,0, CommunicateMediaType.Offline,false,""));
            } else if (msg.what == 1) {
                ToastUtils.showLong(GGApplication.applicationContext, "正在重新连接……!");
            } else if (msg.what == 2) {
            //    ToastUtils.showLong(OrayApplication.applicationContext, "登录成功!");
                EventBus.getDefault().post(new RequestEvent(null,null,0,CommunicateMediaType.Online,false,""));
            } else if (msg.what == 3) {
                ToastUtils.showLong(GGApplication.applicationContext, "您已退出，请重新登录!");
            } else if (msg.what == 4) {
                ToastUtils.showLong(GGApplication.applicationContext, "账号在别处登录，下线!");
                Manager.getInstance().logout();
            } else if (msg.what == 5) {
                ToastUtils.showLong(GGApplication.applicationContext, "被其他用户踢出，下线!");
                Manager.getInstance().logout();
            }
        }
    };

    public static GGApplication getInstance() {
        return instance;
    }

    public GGUser getCurrentUser() {
        return currentUser;
    }

    public void setCurrentUser(GGUser currentUser) {
        this.currentUser = currentUser;
    }

    public IRapidPassiveEngine getEngine() {
        return engine;
    }

    public void setEngine(IRapidPassiveEngine engine) {
        this.engine = engine;
    }

    public ILogger getFileLogger()
    {
        return this.fileLogger;
    }
    public void setFileLogger(FileLogger logger)
    {
        this.fileLogger=logger;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        applicationContext = this;
        instance = this;
        CrashHandler.getInstance().init(this);//设置异常捕捉
    }


    @Override
    public void beingPushedOut() {
        closeAppAndGotoLoginPage();
        uiHandler.obtainMessage(4).sendToTarget();
    }

    @Override
    public void beingKickedOut() {
        closeAppAndGotoLoginPage();
        uiHandler.obtainMessage(5).sendToTarget();
    }

    /*
     * 当我在其他设备上线时
     * */
    @Override
    public void myDeviceOnline(ClientType clientType) {
        ClientGlobalCache.getInstance().addOnlineClientType(clientType);
    }
    /*
     * 当我在其他设备下线时
     * */
    @Override
    public void myDeviceOffline(ClientType clientType) {
        ClientGlobalCache.getInstance().removeOnlineClientType(clientType);
    }



    public void ringForMessage() {
        MediaPlayer player = MediaPlayer.create(applicationContext, R.raw.ring);
        player.start();
    }

    MediaPlayer callingPlayer =null;
    public void ringForCalling(){
        stopRingForCalling();
        callingPlayer = MediaPlayer.create(applicationContext, R.raw.call);
        callingPlayer.start();
        callingPlayer.setLooping(true);
    }

    public void stopRingForCalling() {
        if (callingPlayer != null) {
            callingPlayer.stop();
            callingPlayer.release(); //切记一定要release
            callingPlayer = null;
        }
    }

    void closeEngine() {
        try {
            if (this.getEngine() != null) {
                this.getEngine().setEngineEventListener(null);
                this.getEngine().getContactsOutter().setContactsEventListener(null);
                this.getEngine().getBasicOutter().addBasicEventListener(null);
                this.getEngine().close();
                this.engine = null;
            }
        } catch (Exception ex) {
        }
    }

    void closeAppAndGotoLoginPage() {
        try {
            closeEngine();
            goToLoginPage();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    private void goToLoginPage() {
        IntentUtils.startActivity(this.getApplicationContext(), LoginActivity.class, Intent.ACTION_MAIN, new String[]{Intent.CATEGORY_LAUNCHER},
                new int[]{Intent.FLAG_ACTIVITY_CLEAR_TOP, Intent.FLAG_ACTIVITY_NEW_TASK});
    }

    @Override
    public void echoMessageReceived(ClientType clientType, String destUserID, int messageType, byte[] message, String tag) {
        try {
            switch (ContractType.getContractTypeByCode(messageType)) {
                case CHAT:
                    RichChatMessage richChatMessage = new RichChatMessage();
                    richChatMessage.deserialize(BufferUtils.wrappedBuffer(message));
                    Manager.getInstance().postChatEvent4RichChatMessageReceived(tag,clientType,currentUser.getUserID(),richChatMessage,false,true,"","");
//                    ChatEvent chatEvent = new ChatEvent(tag, clientType, currentUser.getUserID(), richChatMessage, false);
//                    chatEvent.isEcho = true;
//                    EventBus.getDefault().post(chatEvent);
                    break;
                case ChatTransfered:
                    richChatMessage = new RichChatMessage();
                    richChatMessage.deserialize(BufferUtils.wrappedBuffer(message));
                    String[] accepters = tag.split(",");
                    for(String userID :accepters)
                    {
                        ChatEvent  chatEvent = new ChatEvent(userID, ClientType.ANDROID, this.engine.getCurrentUserID(), richChatMessage, userID.contains("*"));
                        chatEvent.isEcho = true;
                        EventBus.getDefault().post(chatEvent);
                    }
                    break;
                case ChangeMyHeadImage:
                    this.userHeadImageChanged(message);
                    break;
                case ChangeMyBaseInfo:
                    ChangeUserBaseInfoContract changeUserBaseInfoContract = new ChangeUserBaseInfoContract();
                    changeUserBaseInfoContract.deserialize(message);
                    ClientGlobalCache.getInstance().updateUserBaseInfo(changeUserBaseInfoContract.UserID, changeUserBaseInfoContract.Name, changeUserBaseInfoContract.Signature, changeUserBaseInfoContract.OrgID, changeUserBaseInfoContract.UserLatestVersion);
                    EventBus.getDefault().post(new UserInfoChangedEvent(changeUserBaseInfoContract.UserID));
                    break;
                case MoveFriendToOtherCatalog:
                    MoveFriendToOtherCatalogContract moveFriendToOtherCatalogContract = new MoveFriendToOtherCatalogContract();
                    moveFriendToOtherCatalogContract.deserialize(message);
                    ClientGlobalCache.getInstance().getCurrentUser().moveFriend(moveFriendToOtherCatalogContract.FriendID,moveFriendToOtherCatalogContract.OldCatalog,moveFriendToOtherCatalogContract.NewCatalog);
                    EventBus.getDefault().post(new FriendCatalogChangedEvent());
                    break;
                case AddFriendCatalog:
                    String catalog = new String(message, StandardCharsets.UTF_8);
                    ClientGlobalCache.getInstance().getCurrentUser().AddFriendCatalog(catalog);
                    EventBus.getDefault().post(new FriendCatalogChangedEvent());
                    break;
                case MediaCommunicate:
                    MediaCommunicateContract mediaCommunicateContract = new MediaCommunicateContract();
                    mediaCommunicateContract.deSeralize(message);
                    if (mediaCommunicateContract.getCommunicateType() == CommunicateType.Agree||mediaCommunicateContract.getCommunicateType() == CommunicateType.Reject) {
                        EventBus.getDefault().post(new CallEvent(currentUser.getUserID(), clientType, messageType, mediaCommunicateContract.getCommunicateMediaType(), mediaCommunicateContract.getCommunicateType(), true,mediaCommunicateContract.getTag()));
                    }
                    break;
                case AudioMessage:
                    AudioMessage audioMessage = new AudioMessage(message);
                    String loginId = audioMessage.creatorID;
                    String userID = loginId;
                    String[] ids = loginId.split("#");
                    if (ids.length > 1) {
                        userID = ids[1];
                    }
                    EventBus.getDefault().post(new ChatEvent(userID, clientType, destUserID, audioMessage, false));
                    break;
                case ChangeUnitCommentName:
                    ChangeCommentNameContract contract = new ChangeCommentNameContract();
                    contract.deSerialize(message);
                    ClientGlobalCache.getInstance().onChangeUnitCommentName(contract.UnitID, contract.CommentName);
                    FriendCommentNameChangedEvent event=new FriendCommentNameChangedEvent(contract.UnitID, ClientGlobalCache.getInstance().getUser(contract.UnitID).getCommentName());
                    EventBus.getDefault().post(event);
                    break;
                case HandleAddFriendRequest:
                    HandleAddFriendRequestContract handleAddFriendRequestContract=new HandleAddFriendRequestContract();
                    handleAddFriendRequestContract.deserialize(message);
                    ClientGlobalCache.getInstance().removeRequestAddFriend(handleAddFriendRequestContract.RequesterID);
                    EventBus.getDefault().post(new HandleRequestAddFriendReceivedEvent());
                    break;
                case HandleAddGroupRequest:
                    this.handleAddGroupRequestReceived(message);
                    break;
                case SnapchatRead:
                    SnapchatMessageRead snapchatMessageRead=new SnapchatMessageRead();
                    snapchatMessageRead.deserialize(message);
                    Manager.getInstance().onSnapchatReadReceived(snapchatMessageRead.SourceCreatorID, snapchatMessageRead);
                    break;
                case ChangeMyPhone:
                    //TO DO: 修改自身的手机号码
                    break;
                case QuitGroup:
                    String groupID = new String(message, StandardCharsets.UTF_8);
                    ClientGlobalCache.getInstance().removeGroup(groupID);
                    EventBus.getDefault().post(new GroupDeletedNotifyEvent(groupID, true));
                    break;
                case DeleteGroup:
                    String groupID2 = new String(message, StandardCharsets.UTF_8);
                    ClientGlobalCache.getInstance().removeGroup(groupID2);
                    EventBus.getDefault().post(new GroupDeletedNotifyEvent(groupID2, true));
                    break;
                case RemoveFriend:
                    String friendID = new String(message, StandardCharsets.UTF_8);
                    Manager.getInstance().removeFriend(friendID);
                    EventBus.getDefault().post(new FriendDeletedNotifyEvent(ClientGlobalCache.getInstance().getUser(friendID) , true));
                    break;
            }
        }catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public void messageReceived(String sourceUserID, ClientType clientType,int messageType, byte[] message, String tag) {
        try
        {
            switch (ContractType.getContractTypeByCode(messageType))
            {
                case CHAT:
                    String senderID = tag;
                    if (senderID.equals(engine.getCurrentUserID()))
                    {
                        return;
                    }
                    RichChatMessage richChatMessage = new RichChatMessage();
                    richChatMessage.deserialize(BufferUtils.wrappedBuffer(message));
                    Manager.getInstance().postChatEvent4RichChatMessageReceived(senderID, clientType, senderID, richChatMessage, false);
                    if (AndroidUtil.isAppIsInBackground(GGApplication.this))
                    {
                        Intent intent = new Intent(this, SplashActivity.class);
                        intent.putExtra("TalkingUserID", senderID);
                        intent.putExtra("isGroup", false);
                        String serderName = ClientGlobalCache.getInstance().getUser(senderID).getName();
                        PendingIntent pendingIntent = PendingIntent.getActivity(GGApplication.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
                        String tips=richChatMessage.getText();
                        if(tips.equals(" ")&&richChatMessage.getNonTextHashMap().size()>0 )
                        {
                            tips="[图片]";
                        }
                        AndroidUtil.showNotifyMessage(GGApplication.this, pendingIntent, serderName,tips,ClientGlobalCache.getInstance().getTotalNotReadMsgCount());
                    }
                    else {
                      if(!ClientGlobalCache.getInstance().getMyOnlineClientTypeContainsPC())
                      {
                          GGApplication.getInstance().ringForMessage();
                      }
                    }

                    break;
                case UserHeadImageChanged:
                    this.userHeadImageChanged(message);
                    break;
                case MediaCommunicate:

                    MediaCommunicateContract communicateContract = new MediaCommunicateContract();
                    communicateContract.deSeralize(message);
                    if(communicateContract.getDestClientType()!=-1&&communicateContract.getDestClientType()!=ClientType.ANDROID.getType())
                    {
                        return;
                    }
                    //收到同意回复，但请求该请求页面已不存在，直接回复中断
                    if ((communicateContract.getCommunicateMediaType() == CommunicateMediaType.Video || communicateContract.getCommunicateMediaType() == CommunicateMediaType.Audio) && communicateContract.getCommunicateType() == CommunicateType.Agree)
                    {
                        if (StringHelper.isNullOrEmpty(CommonOptions.CallingID4VideoOrVoice) || (!StringHelper.isNullOrEmpty(CommonOptions.CallingID4VideoOrVoice) && !CommonOptions.CallingID4VideoOrVoice.equals(sourceUserID)))
                        {
                            Manager.getInstance().sendMediaCommunicate(sourceUserID, communicateContract.getCommunicateMediaType(), CommunicateType.Terminate, null, clientType.getType());
                            return;
                        }
                    }

                    //收到请求是由服务端转发过来的，其他的同意、拒绝、中断是客户端直接发送来的
                    if (communicateContract.getCommunicateType() == CommunicateType.Request) {
                        sourceUserID=tag;//由于请求是服务端转发过来的，sourceUserID是在tag中
                        boolean voiceCallActivityisForeground= AndroidUtil.isForeground(this, VoiceCallActivity.class.getName());
                        boolean videoCallActivityisForeground= AndroidUtil.isForeground(this, VideoCallActivity.class.getName());
                        boolean videoChat4GroupActivityisForeground= AndroidUtil.isForeground(this, VideoChat4GroupActivity.class.getName());
                        boolean videoCall4GroupActivityisForeground= AndroidUtil.isForeground(this, VideoCall4GroupActivity.class.getName());
                        boolean chatActivityisForeground= AndroidUtil.isForeground(this, ChatActivity.class.getName());//当前是否处于聊天页面 （因为聊天页面中MultimediaDeviceType.Microphone一直处于工作状态）
                        //若正处于语音、视频、群聊 的页面，自动拒绝后来的 请求
                        if((!chatActivityisForeground && MultimediaManagerFactory.GetSingleton().deviceIsWorking(MultimediaDeviceType.Microphone))||voiceCallActivityisForeground||videoCallActivityisForeground||videoChat4GroupActivityisForeground||videoCall4GroupActivityisForeground)
                        {
                            LogHelper.i("进入到了页面中");
                            //收到的是群聊视频请求，向所有成员发送拒绝
                            if(communicateContract.getCommunicateMediaType()==CommunicateMediaType.GroupVideo&& !StringHelper.isNullOrEmpty(communicateContract.getTag()))
                            {
                                String[] tag1=  communicateContract.getTag().split(ConfigUtils.ColonSeparator);
                                String videoGroupID=tag1[0];
                                String groupID=tag1[0].split("_")[0];
                                String[] memberIDs=tag1[1].split(ConfigUtils.CommaSeparator);
                                LogHelper.i("进入到了页面中videoGroupID:"+videoGroupID+" memberIDs:"+memberIDs.length);
                                Manager.getInstance().sendSystemMessage(groupID, String.format("设备忙，已拒绝%s的群视频聊天请求",ClientGlobalCache.getInstance().getUserName(sourceUserID)),true);// 发送系统消息
                                Manager.getInstance().sendGroupVideoChat4Reject(videoGroupID,memberIDs,CommunicateType.Busy);
                                return;
                            }
                            //收到的是语音、视频请求，向对方自动发送拒绝
                            Manager.getInstance().sendMediaCommunicate(sourceUserID,communicateContract.getCommunicateMediaType(),CommunicateType.Busy,"",clientType.getType());
                            this.sendSystemMessage4Reject(sourceUserID,communicateContract.getCommunicateMediaType());
                            return;
                        }
                        LogHelper.i("请求，切换到前台");
                        //将应用切换到前台并置顶
                        AndroidUtil.setTopApp(GGApplication.applicationContext,VideoCallActivity.class);
                    }
                    this.postMediaCommunicateMessage(sourceUserID,clientType,messageType,communicateContract);
                    break;
                case AudioMessage:
                    AudioMessage audioMessage = new AudioMessage(message);
                    String loginId = audioMessage.creatorID;
                    String userID = loginId;
                    String[] ids = loginId.split("#");
                    if (ids.length > 1)
                    {
                        userID = ids[1];
                    }
                    EventBus.getDefault().post(new ChatEvent(userID, clientType, userID, audioMessage, false));
                    GGApplication.getInstance().ringForMessage();

                    break;
                case RequestAddFriend:
                    RequestAddFriendContract contract = new RequestAddFriendContract();
                    contract.deserialize(message);
                    ClientGlobalCache.getInstance().addRequestAddFriend(contract.RequesterID);
                    EventBus.getDefault().post(new RequestAddFriendEvent(contract.RequesterID));
                    break;

                case HandleAddFriendRequest:
//                    HandleAddFriendRequestContract handleAddFriendRequestContract=new HandleAddFriendRequestContract();
//                    handleAddFriendRequestContract.deserialize(message);
                    EventBus.getDefault().post(new HandleRequestAddFriendReceivedEvent());
                    break;

                case GetAddFriendPage:
                    AddFriendRequestPage page=new AddFriendRequestPage();
                    page.deserialize(message);
                    GetAddFriendPageEvent event=new GetAddFriendPageEvent(page);
                    EventBus.getDefault().post(event);
                    break;
                case FriendAddedNotify:
                    GGUser friend = new GGUser();
                    friend.deserialize(message);
                    ClientGlobalCache.getInstance().addUser(friend);
                    String catalog = getResources().getString(R.string.friend_catalog_name);
                    if (tag != null)
                    {
                        catalog = tag;
                    }
                    EventBus.getDefault().post(new FriendAddedNotifyEvent(friend,catalog,false));
                break;
                case RequestAddGroup:
                    RequestAddGroupContract requestAddGroupContract = new RequestAddGroupContract();
                    requestAddGroupContract.deserialize(message);
                    ClientGlobalCache.getInstance().addRequestAddGroup(requestAddGroupContract.RequesterID,requestAddGroupContract.GroupID);
                    RequestAddGroupEvent requestAddGroupEvent= new RequestAddGroupEvent(requestAddGroupContract.RequesterID,requestAddGroupContract.GroupID);

                    EventBus.getDefault().post(requestAddGroupEvent);
                    break;
                case HandleAddGroupRequest:
                    this.handleAddGroupRequestReceived(message);
                    break;
                case GetAddGroupPage:
                    AddGroupRequestPage addGroupRequestPage = new AddGroupRequestPage();
                    addGroupRequestPage.deserialize(message);
                    GetAddGroupPageEvent getAddGroupPageEvent = new GetAddGroupPageEvent(addGroupRequestPage);
                    EventBus.getDefault().post(getAddGroupPageEvent);
                    break;
                case GroupBan4User:
                    GroupBan4UserContract groupBan4UserContract = new GroupBan4UserContract();
                    groupBan4UserContract.deserialize(message);
                    GroupBan4UserEvent groupBan4UserEvent = new GroupBan4UserEvent(groupBan4UserContract.GroupID, groupBan4UserContract.OperatorID, groupBan4UserContract.UserID, groupBan4UserContract.Minutes);
                    EventBus.getDefault().post(groupBan4UserEvent);
                    break;
                case RemoveGroupBan4User:
                    RemoveGroupBan4UserContract removeGroupBan4UserContract = new RemoveGroupBan4UserContract();
                    removeGroupBan4UserContract.deserialize(message);
                    RemoveGroupBan4UserEvent removeGroupBan4UserEvent = new RemoveGroupBan4UserEvent(removeGroupBan4UserContract.GroupID, removeGroupBan4UserContract.UserID);
                    EventBus.getDefault().post(removeGroupBan4UserEvent);

                    break;
                case Snapchat:
                    // TO DO 添加自焚消息
                    sourceUserID = tag;
                    SnapchatMessage snapchatMessage=new SnapchatMessage();
                    snapchatMessage.deserialize(message);
                    Manager.getInstance().onSnapchatMessageReceived(sourceUserID,clientType, snapchatMessage);

                    break;
                case SnapchatRead:
                    // TO DO 移除自焚消息
                    SnapchatMessageRead snapchatMessageRead=new SnapchatMessageRead();
                    snapchatMessageRead.deserialize(message);
                    Manager.getInstance().onSnapchatReadReceived(sourceUserID,snapchatMessageRead);
                    break;
                case UserStateChanged:
                {
                    UserState userState = UserState.getUserStateByCode(Integer.parseInt(tag)) ;
                    ClientGlobalCache.getInstance().getCurrentUser().UserState= userState;
                    return;
                }
            }
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }



    @Override
    public void handleInformation(String sourceUserID, ClientType clientType, int messageType, byte[] bytes) {
        try {
            switch (ContractType.getContractTypeByCode(messageType)) {
                case Vibration: {
                   // EventBus.getDefault().post(new ChatEvent(sourceUserID, clientType, true));
                }
                break;
                case UserStatusChanged: {
                    UserStatusChangedContract uscc = new UserStatusChangedContract();
                    uscc.deserialize(bytes);
                    ClientGlobalCache.getInstance().onUserStatusChanged(uscc.getUserID(), uscc.getStatus());
                    EventBus.getDefault().post(new UserEvent(uscc.getUserID(), uscc.getStatus()));
                }
                break;
                case OfflineMessage: {
                    try {
                        OfflineMessage om = new OfflineMessage();
                        om.deserialize(bytes);
                        RichChatMessage chatMsg = new RichChatMessage();
                        chatMsg.deserialize(BufferUtils.wrappedBuffer(om.getInformation()));
                        chatMsg.TransferTime=om.getTime();
                        if (om.getInformationType() == ContractType.GroupChat.getType()) {
                            Manager.getInstance().postChatEvent4RichChatMessageReceived(om.getGroupID(),clientType,om.getSourceUserID(),chatMsg,true);
                        } else  if(om.getInformationType()==ContractType.CHAT.getType()){
                            Manager.getInstance().postChatEvent4RichChatMessageReceived(om.getSourceUserID(),clientType,om.getSourceUserID(),chatMsg,false);
                        }
                        else if(om.getInformationType()==ContractType.Snapchat.getType())
                        {
                            SnapchatMessage snapchatMessage=new SnapchatMessage();
                            snapchatMessage.deserialize(om.getInformation());
                            Manager.getInstance().onSnapchatMessageReceived(om.getSourceUserID(),clientType,snapchatMessage);
                            // TO DO 添加自焚消息
                        }
                        if (om.getInformation() != null && om.getInformation().length > 0) {
                            GGApplication.getInstance().ringForMessage();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                break;
                case GroupOfflineMessage:
                    GroupOfflineMessage groupOfflineMessage =new GroupOfflineMessage();
                    groupOfflineMessage.deserialize(bytes);
                    for (OfflineMessage msg :groupOfflineMessage.OfflineMessages) {
                        RichChatMessage chatMsg = new RichChatMessage();
                        chatMsg.deserialize(BufferUtils.wrappedBuffer(msg.getInformation()));
                        chatMsg.TransferTime=msg.getTime();
                        Manager.getInstance().postChatEvent4RichChatMessageReceived(msg.getGroupID(), clientType, msg.getSourceUserID(), chatMsg, true);
                    }
                    break;
                case MediaCommunicate: {
                    //收到请求
                    MediaCommunicateContract mcc = new MediaCommunicateContract();
                    try {
                        mcc.deSeralize(bytes);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if(mcc.getDestClientType()!=-1&&mcc.getDestClientType()!=ClientType.ANDROID.getType())
                    {
                        return;
                    }

                }
                break;

                case FriendRemovedNotify:{
                    String friendID =   new String(bytes, StandardCharsets.UTF_8);
                    EventBus.getDefault().post(new FriendDeletedNotifyEvent(ClientGlobalCache.getInstance().getUser(friendID),false));
                    break;
                }
                case SomeoneRegisteredNotify:{
                    GGUser friend = new GGUser();
                    friend.deserialize(bytes);
                    ClientGlobalCache.getInstance().addUser(friend);
                    EventBus.getDefault().post(new SomeoneRegisteredEvent(friend));
                }
                break;
                case UserBaseInfoChanged:
                    ChangeUserBaseInfoContract changeUserBaseInfoContract=new ChangeUserBaseInfoContract();
                    changeUserBaseInfoContract.deserialize(bytes);
                    ClientGlobalCache.getInstance().updateUserBaseInfo(changeUserBaseInfoContract.UserID,changeUserBaseInfoContract.Name,changeUserBaseInfoContract.Signature,changeUserBaseInfoContract.OrgID,changeUserBaseInfoContract.UserLatestVersion);
                    EventBus.getDefault().post(new UserInfoChangedEvent(changeUserBaseInfoContract.UserID));
                    break;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    /**
     * Post多媒体消息
     * */
    public void postMediaCommunicateMessage(String sourceUserID,ClientType sourceClientType,int messageType, MediaCommunicateContract mediaCommunicateContract)
    {
        if (mediaCommunicateContract.getCommunicateType() == CommunicateType.Request)
        {
            LogHelper.e("进入MediaCommunicate——Request");
            EventBus.getDefault().post(new RequestEvent(sourceUserID, sourceClientType, messageType, mediaCommunicateContract.getCommunicateMediaType(), false,mediaCommunicateContract.getTag()));
        } else
        {
            LogHelper.e("进入MediaCommunicate——Other");
            EventBus.getDefault().post(new CallEvent(sourceUserID, sourceClientType, messageType, mediaCommunicateContract.getCommunicateMediaType(), mediaCommunicateContract.getCommunicateType(), false,mediaCommunicateContract.getTag()));
            LogHelper.e("结束MediaCommunicate——Other");
        }
    }

    /**
     * 获取多媒体消息文本描述
     * */
    private String getCommunicateMediaStr(MediaCommunicateContract communicateContract)
    {
        String str1= "";
        switch (communicateContract.getCommunicateType())
        {
            case Agree:
                str1="同意了";
                break;
            case Reject:
                str1="拒绝了";
                break;
            case Request:
                str1="邀请您进行";
                break;
            case Terminate:
                str1="中断了";
                break;
        }

        String str2= "";
        switch (communicateContract.getCommunicateMediaType())
        {
            case Video:
                str2="视频通话";
                break;
            case Audio:
                str2="语音通话";
                break;
            case GroupVideo:
                str2="群视频通话";
                break;
        }
        return str1+str2;
    }

    /**
     * 发送自动拒绝系统消息
     * */
    private void sendSystemMessage4Reject(String requestID,CommunicateMediaType communicateMediaType)
    {
        switch (communicateMediaType)
        {
            case Audio:
                Manager.getInstance().sendSystemMessage(requestID, String.format("设备忙，已拒绝%s的语音聊天请求",ClientGlobalCache.getInstance().getUserName(requestID)),false);
                break;
            case Video:
                Manager.getInstance().sendSystemMessage(requestID, String.format("设备忙，已拒绝%s的视频聊天请求",ClientGlobalCache.getInstance().getUserName(requestID)),false);
                break;
        }

    }

    @Override
    public byte[] handleQuery(String sourceUserID, ClientType clientType, int messageType, byte[] bytes) {
        return new byte[0];
    }

    private void userHeadImageChanged(byte[] message)
    {
        try {
            ChangeHeadImageContract changHeadImageContract = new ChangeHeadImageContract();
            changHeadImageContract.deserialize(message);
            GGUser GGUser = ClientGlobalCache.getInstance().getUser4Cache(changHeadImageContract.UserID);
            if (GGUser != null) {
                GGUser.updateHeadImage(changHeadImageContract.HeadImageIndex, changHeadImageContract.HeadImage);
                GGUser.setVersion(changHeadImageContract.UserLatestVersion);
                ClientGlobalCache.getInstance().updateUser(GGUser);
                //EventBus.getDefault().post(new UserHeadImageChangedEvent(changHeadImageContract.UserID,changHeadImageContract.HeadImageIndex,changHeadImageContract.HeadImage));
                ClientGlobalCache.getInstance().UpdateUserInLocalDB(GGUser);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //收到请求加入组的处理消息
    private void handleAddGroupRequestReceived(byte[] message)
    {
        try {
            HandleAddGroupRequestContract contract=new HandleAddGroupRequestContract();
            contract.deserialize(message);
            EventBus.getDefault().post(new HandleRequestAddGroupReceivedEvent());
            if(contract.IsAgreed&&contract.RequesterID.equals(ClientGlobalCache.getInstance().getCurrentUser().getUserID()))
            {
//                List<String> groupList=new ArrayList<>();
//                groupList.add(contract.GroupID);
//                ClientGlobalCache.getInstance().resetSomeGroups(groupList);
                GGGroup group =ClientGlobalCache.getInstance().getGroup(contract.GroupID);
                List<String> guests=new ArrayList<>();
                guests.add(ClientGlobalCache.getInstance().getCurrentUser().getUserID());
                EventBus.getDefault().post(new GroupUserChangedEvent(contract.GroupID, GroupChangedType.MyselfBePulledIntoGroup, group.getCreatorID(),guests));
            }
        }catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

